package com.example.security.service;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.common.core.response.AjaxResult;
import com.example.common.enums.CommonMessage;
import com.example.common.enums.UserRoleEnum;
import com.example.common.system.dao.MenuDao;
import com.example.common.system.dao.RoleMenuDao;
import com.example.common.system.entity.*;
import com.example.common.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author chenjf
 * @Date 2022/9/20
 * @Description
 */
@Service
public class LoginService {

//    @Value("${example.login.max}")
//    private Integer maxLogin;

    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private RoleMenuDao roleMenuDao;

    @Autowired
    private MenuDao menuDao;

    @Value("${session.code}")
    private Boolean sessionCodeIfTrue;

    @Autowired
    private HttpSession session;

    public AjaxResult login(UserEntity user) {
        //1.检验验证码
        //验证码是否开启
        if (sessionCodeIfTrue) {
            //验证码
            String sessionCode = (String) session.getAttribute(user.getUuid());
            if (StrUtil.isEmpty(sessionCode)){
                return AjaxResult.warn(HttpStatus.BAD_REQUEST,null,"验证码已过期");
            }
            String code = user.getCode();
            if (!sessionCode.equals(code)) {
                return AjaxResult.warn(HttpStatus.BAD_REQUEST,null,"验证码不正确");
            }
        }
        //2.查询账号密码是否正确
        Authentication authenticate = null;
        try {
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));
        } catch (AuthenticationException e) {
            return AjaxResult.warn(HttpStatus.BAD_REQUEST,null,"用户名或密码错误");
        }
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        //添加权限标识
        HashSet<String> strings = null;
        if (loginUser.isAdmin()){
             strings = new HashSet<>();
             strings.add("*:*:*");
            loginUser.setPermissions(strings);
        }
        //去数据库查询权限
        List<RoleEntity> roles = loginUser.getRoles();
        Iterator<RoleEntity> iterator = roles.iterator();
        //所有的角色id
        ArrayList<Long> longs = new ArrayList<>();
        while (iterator.hasNext()){
            longs.add(iterator.next().getId());
        }
        //根据角色获取所有权限
        List<RoleMenuEntity> roleMenuEntities = roleMenuDao.selectList(new LambdaQueryWrapper<RoleMenuEntity>().in(RoleMenuEntity::getRoleId, longs));
        if (roleMenuEntities != null && roleMenuEntities.size()>0){
            Iterator<RoleMenuEntity> iterator1 = roleMenuEntities.iterator();
            ArrayList<Long> roleList = new ArrayList<>();
            while (iterator1.hasNext()){
                roleList.add(iterator1.next().getMenuId());
            }
            //给用户设置权限
            loginUser.setPermissions(menuDao.selectAllPermission(roleList));
        }
        //4.创建token返回token信息
        String token = generateToken();
        //加入缓存30分
        String sysUser = JSON.toJSONString(loginUser);
        redisUtil.setEx(CommonMessage.REDIS_TOKEN.getValue() + token, sysUser, 30, TimeUnit.MINUTES);
        return AjaxResult.success(token, "登录成功");
    }





//    /**
//     * 是否满员
//     *
//     * @return
//     */
//    public Boolean isItFull(Long userId) {
//        if (null == maxLogin) {
//            return true;
//        }
//        List<String> exist = new ArrayList<>();
//        //获取所有数据
//        List<String> strings = redisUtil.lGetAll(CommonMessage.USER_TOKEN_COUNT.getValue() + userId);
//        for (String value : strings) {
//            Boolean aBoolean = redisUtil.hasKey(CommonMessage.REDIS_TOKEN.getValue() + value);
//            if (aBoolean) {
//                exist.add(value);
//            }
//        }
//        if (maxLogin >= exist.size()) {
//            return false;
//        } else {
//            Long aLong = redisUtil.lLeftPushAll(CommonMessage.USER_TOKEN_COUNT.getValue() + userId, exist);
//            if (aLong == exist.size()) {
//                return true;
//            }
//            return false;
//        }
//    }

    private String generateToken() {
        return UUID.randomUUID().toString().replace("-", "");
    }
}
